package com.gvtv.main.quartz;

import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

import java.io.File;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;

import com.gvtv.main.schedul.SchedulInfo;
import com.gvtv.main.util.AppTools;
import com.gvtv.main.util.Constant;

public class QuartzService {

	private static final Logger logger = Logger.getLogger(QuartzService.class);

	private static String QUARTZ_PROPERTIES = "/conf/quartz.properties";
	private static String QUARTZ_GROUP = "QUARTZ_GROUP";
	private static String QUARTZ_GRIGGER_GROUP = "QUARTZ_TRIGGER_GROUP";

	public static String EXE_SCHEDUL = "EXE_SCHEDUL";
	private Scheduler scheduler = null;
	private static byte[] lock = new byte[0];
	private static QuartzService instance;

	public static QuartzService getInstance() {
		if (instance != null) {
			return instance;
		} else {
			synchronized (lock) {
				if (instance != null) {
					return instance;
				} else {
					instance = new QuartzService();
					return instance;
				}
			}
		}
	}

	public QuartzService() {
		try {
			String properties = AppTools.getBaseDir() + QUARTZ_PROPERTIES;
			if (new File(properties).exists()) {
				scheduler = new StdSchedulerFactory(properties).getScheduler();
			} else {
				scheduler = StdSchedulerFactory.getDefaultScheduler();
				logger.info(properties + "文件不存在，使用quartz默认的调度器.");
			}
		} catch (SchedulerException e) {
			logger.error("初始化quartz调度器失败。。。" + e);
		}
	}

	public void addSchedul(SchedulInfo schedulInfo) throws SchedulerException {
		
		DateTime startTime = null;
		JobDetail jobDetail = newJob(QuartzExeJob.class).withIdentity(schedulInfo.getId(), QUARTZ_GROUP).build();

		TriggerBuilder<Trigger> triggerBuilder = newTrigger().withIdentity("trigger_" + schedulInfo.getId(), QUARTZ_GRIGGER_GROUP);
		if (StringUtils.isNotBlank(schedulInfo.getStartTime())) {
			startTime = DateTime.parse(schedulInfo.getStartTime(), DateTimeFormat.forPattern(Constant.DATETIME_FORMAT));
		}else {
			startTime = new DateTime();
		}
		triggerBuilder.startAt(startTime.toDate());
		if (StringUtils.isNotBlank(schedulInfo.getEndTime())) {
			DateTime endTime = DateTime.parse(schedulInfo.getEndTime(), DateTimeFormat.forPattern(Constant.DATETIME_FORMAT));
			if (endTime.isAfter(startTime)) {
				triggerBuilder.endAt(endTime.toDate());
			} else {
				logger.warn("结束时间[" + endTime + "]小于开始时间[" + startTime + "]，忽略结束时间");
			}
		}
		if (StringUtils.isNotBlank(schedulInfo.getCron())) {
			triggerBuilder.withSchedule(cronSchedule(schedulInfo.getCron()));
		} else {
			logger.info("调度表达式为空，调度作业只运行一次。");
		}
		Trigger trigger = triggerBuilder.build();
		jobDetail.getJobDataMap().put(EXE_SCHEDUL, schedulInfo);
		try {
			scheduler.scheduleJob(jobDetail, trigger);
			logger.info("添加调度作业[" + schedulInfo.getId() + "]到quartz调度器中。。。");
		} catch (SchedulerException e) {
			logger.error("添加调度作业[" + schedulInfo.getId() + "]到quartz调度器失败。。。" + e);
			throw new SchedulerException("添加调度作业[" + schedulInfo.getId() + "]失败.", e);
		}
	}

	public void removeSchedul(SchedulInfo schedulInfo) throws SchedulerException {
		TriggerKey triggerKey = new TriggerKey("trigger_" + schedulInfo.getId(), QUARTZ_GRIGGER_GROUP);
		try {
			scheduler.pauseTrigger(triggerKey);
			scheduler.unscheduleJob(triggerKey);
			scheduler.deleteJob(new JobKey(schedulInfo.getId(), QUARTZ_GROUP));
		} catch (SchedulerException e) {
			logger.error("删除调度作业[" + schedulInfo.getId() + "]失败。。。" + e);
			throw new SchedulerException("删除调度作业[" + schedulInfo.getId() + "]失败.", e);
		}
	}

	public void start() {
		try {
			scheduler.start();
			logger.info("quartz调度启动。。。");
		} catch (SchedulerException e) {
			logger.error("quartz调取器启动失败。" + e);
		}
	}

	public void stop() {
		try {
			//if(!scheduler.isShutdown()&&scheduler.isStarted()){
				scheduler.shutdown(true);
				logger.info("quartz调度停止。。。");
			//}
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}
}
